#ifndef GTKUTILS_H
# define GTKUTILS_H

#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <glib.h>

#include <stdbool.h>

// typedef enum { /*< prefix=G_BINDING >*/
//   G_BINDING_DEFAULT        = 0,

//   G_BINDING_BIDIRECTIONAL  = 1 << 0,
//   G_BINDING_SYNC_CREATE    = 1 << 1,
//   G_BINDING_INVERT_BOOLEAN = 1 << 2
// } GBindingFlags;

// ------------------------------------ Object Controller
// GBinding *g_object_bind_property(gpointer source, const gchar *source_property, gpointer target, const gchar *target_property, GBindingFlags flags);
#define objectBindProperty(s,sp,t,tp,flags) g_object_bind_property(s, sp, t, tp, flags);
typedef GBinding*(*objectBindProperty)(gpointer source, const gchar *source_property, gpointer target, const gchar *target_property, GBindingFlags flags);

#define objectSet(obj, property, argc...) g_object_set(obj, property, ##argc, NULL)
typedef void(*objectSet)(gpointer object, const gchar *first_property_name, ...);
void objectUnref(gpointer obj);

// ------------------------------------ Signal Connection
typedef void(*signalFunc);  //(GtkWidget *widget, gpointer user_data);
typedef void(*signalSwappendFunc);  //(gpointer user_data, GtkWidget *widget);
#define createSignalFunc(func) static void func(GtkWidget *widget, gpointer user_data)
#define createSignalSwappedFunc(func) static void func(gpointer user_data, GtkWidget *widget)
#define createSignalObjectFunc(func, type) static void func(GtkWidget *widget, type *user_data)
#define createSignalSwappedObjectFunc(func, type) static void func(type *user_data, GtkWidget *widget)
typedef void(*createSignalFunc);
typedef void(*createSignalSwappedFunc);
typedef void(*createSignalObjectFunc);
typedef void(*createSignalSwappedObjectFunc);


// Universal
void connectTargetAction(gpointer target, gpointer source, gchar *action, signalFunc call_action);
void connectTargetSwappedAction(gpointer target, gpointer source, gchar *action, signalSwappendFunc call_action);

// ---- Custome 
// Button
void connectButtonClickAction(gpointer target, GtkButton* button, signalFunc clicked_action);
void connectButtonClickSwappedAction(gpointer target, GtkButton* button, signalSwappendFunc clicked_swap_action);
void connectButtonClickAndSwappedAction(gpointer target, GtkButton* button, signalFunc clicked_action, signalSwappendFunc clicked_swap_action);
GtkButton* createButtonAction(gpointer target, const gchar *label, signalFunc clicked_action);
GtkButton* createButtonSwappedAction(gpointer target, const gchar *label, signalSwappendFunc clicked_swap_action);


// ------------------------------------ Widgets Creator
// GtkWidget* createWidgets((GtkWidget*) widget_type, gchar *label) {}
GtkApplication * createApplication(const gchar *label, GApplicationFlags flags);
GtkApplication * createApplicationConnectActivate(const gchar *label, GApplicationFlags flags, gpointer activate);
// App run
gint runApplication(gpointer app, gint argc, gchar **argv);
// Button
GtkButton* createButton(const gchar *label);
GtkButton* createButtonExpand(const gchar *label);
// CheckButton
GtkCheckButton* createCheckButton(const gchar *label);
// Label
GtkLabel* createLabel(const gchar *label);
// Entry Buffer
GtkEntryBuffer* createEntryBuffer();
GtkEntryBuffer* createEntryBufferWithText(gchar *text);

#define entryBufferGetText(buffer) gtk_entry_buffer_get_text(buffer)
typedef const char*(*entryBufferGetText)(GtkEntryBuffer *buffer);

#define entryBufferSetText(buffer, chars) gtk_entry_buffer_set_text(buffer, chars, -1)
typedef void(*entryBufferSetText)(GtkEntryBuffer *buffer, const char *chars, int n_chars);

// Entry
GtkEntry* createEntry();
GtkEntry* createEntryExpand();
GtkEntry* createEntryWithEntryBuffer(GtkEntryBuffer *buffer);

#if GTK_MAJOR_VERSION == 4
// Text
GtkText* createText();
#endif

// TextBuffer
GtkTextBuffer* createTextBuffer(GtkTextTagTable *table);
#define textBufferGetText(buffer, start, end, include_hidden_chars) gtk_text_buffer_get_text(buffer, start, end, include_hidden_chars)
typedef char*(*textBufferGetText)(GtkTextBuffer *buffer, const GtkTextIter *start, const GtkTextIter *end, gboolean include_hidden_chars);

#define textBufferSetText(buffer, text, len) gtk_text_buffer_set_text(buffer, text, len)
typedef void(*textBufferSetText)(GtkTextBuffer *buffer, const char *text, int len);
// void textBufferSetText(GtkTextBuffer *buffer, const char *text, int len) {
//     gtk_text_buffer_set_text(buffer, text, len);
// }

// TextView
GtkTextView* createTextView();
GtkTextView* createTextViewWithTextBuffer(GtkTextBuffer* text_buffer);

// Box - Layout
GtkBox* createBox(GtkOrientation orientation, gint spacing);
// ComboBox
GtkComboBox* createComboBox();
GtkComboBox* createComboBoxExpand();
GtkComboBox* createComboBoxWithEntry();
GtkComboBox* createComboBoxWithModel(GtkTreeModel *model);
GtkComboBox* createComboBoxWithModelUnref(GtkTreeModel *model);
// Frame
GtkFrame* createFrame(const gchar *label);
// ProgreesBar
GtkProgressBar* createProgressBar();

// HeaderBar
GtkHeaderBar* createHeaderBar();

// ------------------------------------ Window decorations
void setWindowHeaderBar(gpointer window, gpointer bar);
void setWindowTitle(gpointer window, const gchar *title);
void setWindowSize(gpointer window, gint width, gint height);
// Window
void setWindowTitleSize(gpointer window, const gchar *title, gint width, gint height);
GtkWindow* createWindowWithTitleSize(GtkApplication *app, const gchar *title, gint width, gint height);
void setWindowChild(gpointer window, gpointer widget);
void showWindow(gpointer window);
void closeWindow(gpointer window);

// Frame
void setFrameChild(gpointer frame, gpointer widget);
GtkFrame* createFrameWithChild(const gchar *label, gpointer widget);

// Button
void setButtonTooltipText(gpointer button, char *text);
// ...
gpointer createWidgetTooltipText(gpointer widget, char *text);

// ------------------------------------ Layout Manage
// 设置控件的展开对齐
typedef enum {
    AFILL,ASTART,AEND,ACENTER,ABASELINE
} WidgetAlign;
void setWidgetHorizntalAlign(gpointer widget, WidgetAlign align);
void setWidgetVerticalAlign(gpointer widget, WidgetAlign align);

void setWidgetHorizntalExpand(gpointer widget, gboolean expand);
void setWidgetVerticalExpand(gpointer widget, gboolean expand);

typedef gpointer(*createFunc)();
gpointer createWidgetHorizntalExpand(gpointer widget, gboolean expand);
gpointer createWidgetVerticalExpand(gpointer widget, gboolean expand);
gpointer createWidgetHorizntalExpandWithFunc(createFunc func, gboolean expand);
gpointer createWidgetVerticalExpandWithFunc(createFunc func, gboolean expand);

// 设置控件的起始边距
void setWidgetMargin(gpointer box, gint start, gint end, gint top, gint bottom);
void setWidgetFullMargin(gpointer widget, gint margin);

// Box - Layout
GtkBox* createBoxWithOrientation(GtkOrientation orientation, gint spacing);
GtkBox* createBoxWithHorizntal(gint spacing);
GtkBox* createBoxWithVertical(gint spacing);
GtkBox* createBoxWithHorizntalMargin(gint spacing, gint margin);
GtkBox* createBoxWithVerticalMargin(gint spacing, gint margin);

// GtkBox* createBoxWithVerticalAppends(gint spacing, gpointer chiled, ...);
// typedef GtkBox* (*createBoxWithVerticalAppendsFinish)(gint spacing, gpointer chiled, ...);
// #define createBoxWithVerticalAppendsFinish(spacing, chiled...) createBoxWithVerticalAppends(spacing, ##chiled, NULL)
#define createAppendsFinish(ret, func, args...)     \
    ret func(##args);                               \
    typedef ret (*func##Finish)(##args);\
    define func##Finish(args1) func(##args1, );


// ┌──────────────────────────────────────────────────────────────────────────────┐
// │ va_list     TYPE以保存有关变量参数的信息(TYPE)。                                  │
// │ va_start    初始化变量参数列表(宏)。                                             │
// │ va_arg      检索下一个参数(宏)                                                  │
// │ va_end      使用变量参数列表(宏)结束。                                           │
// │ vsprintf    将格式化数据从变量参数列表写入字符串(函数)                              │
// └──────────────────────────────────────────────────────────────────────────────┘
static void boxAppendValist(GtkBox *box, gpointer child, va_list args);
void boxAppend(GtkBox *box, gpointer widget);
void boxAppends(GtkBox *box, gpointer chiled, ...);
// Box - Horizntal - Margin - Align
GtkBox* createBoxWithHorizntalAppends(gint spacing, gpointer chiled, ...);
GtkBox* createBoxWithHorizntalMarginAppends(gint spacing, gint margin, gpointer chiled, ...);
GtkBox* createBoxWithHorizntalMarginAlignAppends(gint spacing, gint margin, WidgetAlign align, gpointer chiled, ...);
GtkBox* createBoxWithHorizntalMarginExpandAppends(gint spacing, gint margin, gboolean expand, gpointer chiled, ...);

// Box - Vertical - Margin - Align
GtkBox* createBoxWithVerticalAppends(gint spacing, gpointer chiled, ...);
// typedef GtkBox *(*createBoxWithVerticalAppendsFinish)(gint spacing, gpointer chiled, ...);
// #define createBoxWithVerticalAppendsFinish(args...) createBoxWithVerticalAppends(##args, NULL)

GtkBox* createBoxWithVerticalMarginAppends(gint spacing, gint margin, gpointer chiled, ...);
// typedef GtkBox *(*createBoxWithVerticalMarginAppendsFinish)(gint spacing, gint margin, gpointer chiled, ...);
// #define createBoxWithVerticalMarginAppendsFinish(args...) createBoxWithVerticalMarginAppends(##args)

GtkBox *createBoxWithVerticalMarginAlignAppends(gint spacing, gint margin, WidgetAlign align, gpointer chiled, ...);
// typedef GtkBox *(*createBoxWithVerticalMarginAlignAppendsFinish)(gint spacing, gint margin, WidgetAlign align, gpointer chiled, ...);
// #define createBoxWithVerticalMarginAlignAppendsFinish(args...) createBoxWithVerticalMarginAlignAppends(##args)

GtkBox *createBoxWithVerticalMarginExpandAppends(gint spacing, gint margin, gboolean expand, gpointer chiled, ...);
// typedef GtkBox *(*createBoxWithVerticalMarginExpandAppendsFinish)(gint spacing, gint margin, gboolean expand, gpointer chiled, ...);
// #define createBoxWithVerticalMarginExpandAppendsFinish(args...) createBoxWithVerticalMarginExpandAppends(##args, NULL);


#define setBoxMargin(box, a, b, c, d) setWidgetMargin(box, a, b, c, d)
#define setBoxFullMargin(box, a) setWidgetFullMargin(box, a)
typedef void(*setBoxMargin);
typedef void(*setBoxFullMargin);

// 设置控件的展开对齐
#define setBoxHorizntalExpand(widget, v) setWidgetHorizntalExpand(widget, v)
#define setBoxVerticalExpand(widget, v)  setWidgetVerticalExpand(widget, v)
typedef void(*setBoxHorizntalExpand);
typedef void(*setBoxVerticalExpand);
// 
#define setBoxHorizntalAlign(widget, a) setWidgetHorizntalAlign(widget, a)
#define setBoxVerticalAlign(widget, a)  setWidgetVerticalAlign(widget, a)
typedef void(*setBoxHorizntalAlign);
typedef void(*setBoxVerticalAlign);



// Separator
GtkSeparator* createSeparatorWithOrientation(GtkOrientation orientaion);
GtkSeparator* createSeparatorWithHorizntal();
GtkSeparator* createSeparatorWithVertical();

// ComboBox
void setComboBoxActive(GtkComboBox *combo_box, int index);
gboolean getComboBoxActiveIter(GtkComboBox *combo_box, GtkTreeIter *iter);
#define getComboBoxModel(combo_box) gtk_combo_box_get_model(combo_box)
typedef GtkTreeModel*(*getComboBoxModel)(GtkComboBox *combo_box);
// gchar* getComboBoxActiveText(GtkComboBox *combo_box) {
//     gtk_combo_box_get_entry_text_column(combo_box, )
// }

// ------------------------------------ TreeModel
#define createTreeModelFunc(func) GtkTreeModel* func(void)
typedef GtkTreeModel*(*createTreeModelFunc)(void);
typedef GtkTreeModel*(*createTreeModel)(void);

#define createTreeModelWithFunc(model, createTreeModel) GtkTreeModel* model = createTreeModel()
#define treeModelWithFunc(model, createTreeModel) model = createTreeModel()

#define convTreeModel(obj) GTK_TREE_MODEL(obj)
typedef void(convTreeModel)(gpointer*);

#define treeModelGet(tree_model, iter, argc...) gtk_tree_model_get(tree_model, iter, ##argc, -1)
typedef void(*treeModelGet)(GtkTreeModel *model, GtkTreeIter *iter, ...);

// TreeModel Foreach
#define createTreeModelForeachFunc(func) gboolean func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
typedef gboolean(*createTreeModelForeachFunc)(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);



// 扩展：ComboBox Utils 
GtkComboBox* createComboBoxWithModelFuncUnref(createTreeModel func);
GtkComboBox* createComboBoxWithModelFuncUnrefActive(createTreeModel func, int index);



// GtkTreeModel* createTreeModelWithComboBox(GtkComboBox *combo) {
//     return gtk_combo_box_get_model(combo);
// }

// ------------------------------------ TreePath
// 返回iter引用的新创建的GtkTreePath。
// 应该使用gtk_tree_path_free()释放该路径。
// GtkTreePath *gtk_tree_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)

GtkTreePath* createTreePath();
GtkTreePath* createTreePathWithTreeModel(GtkTreeModel *tree_model, GtkTreeIter *iter);
typedef GtkTreePath*(*treeModelGetPath)(GtkTreeModel *tree_model, GtkTreeIter *iter);
#define treeModelGetPath(tree_model, iter) createTreePathWithTreeModel(tree_model, iter)
void destroyTreePath(GtkTreePath *path);
// 返回路径的当前索引。
// 这是一个整数数组，每个整数表示树中的一个节点。这个值不应该被释放。
// 数组的长度可以通过gtk_tree_path_get_depth()获得。
// int *gtk_tree_path_get_indices(GtkTreePath *path)
int *treePathGetIndices(GtkTreePath *path);
#define treePathGetDepth(path) gtk_tree_path_get_depth(path)
typedef int(*treePathGetDepth)(GtkTreePath *path);

// ------------------------------------ Renderer
GtkCellRendererPixbuf* createCellRendererPixbuf();
GtkCellRendererText* createCellRendererText();
GtkCellRendererProgress* createCellRendererProgress();
GtkCellRendererSpin* createGtkCellRendererSpin();
// gtk_cell_renderer_new()


// ------------------------------------ Cell Layout
// Gtk.CellLayout.pack_start
// 将单元格打包到cell_layout的开头。
// 如果expand为FALSE，则单元格分配的空间不会超过它所需的空间。
// 任何未使用的空间被均匀地分配到扩展为TRUE的单元格之间。
// 注意，不支持重用相同的单元格呈现程序。

// void (*GtkCellLayoutDataFunc)(GtkCellLayout *, GtkCellRenderer *,GtkTreeModel *, GtkTreeIter *, gpointer)
#define createCellLayoutDataFunc(func) void func(GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
// #define createCellLayoutDataFunc(func) gboolean func(void)
typedef void(*createCellLayoutDataFunc);

void setCellLayoutExpand(gpointer widget, gpointer renderer, const char *attributes, gint colume, GtkCellLayoutDataFunc func, gboolean expand);
// 设置单元格处理器，
void setCellLayout(gpointer widget, gpointer renderer, const char *attributes, gint colume, GtkCellLayoutDataFunc func, gboolean expand);

// GtkTreeViewRowSeparatorFunc
#define createTreeViewRowSeparatorFunc(func) gboolean func(GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)

// 扩展：ComboBox Utils 
// Usage：
// 设置行分隔符函数，该函数用于确定是否应将行绘制为分隔符。
// 如果行分隔符函数为NULL，则不绘制分隔符。这是默认值。
// func 应该以 createTreeViewRowSeparatorFunc 宏创建
void setComboBoxRowSeparatorFunc(gpointer combo, GtkTreeViewRowSeparatorFunc func, gpointer data, GDestroyNotify destroy);

// ------------------------------------ List Store
#define createListStoreFunc(func) GtkListStore* func(void)
typedef GtkListStore*(*createListStoreFunc)(void);

// 创建可存储列表
#define createListStore(n, argc...) gtk_list_store_new(n, ##argc)
typedef GtkListStore*(*createListStore)(gint n, ...);

// extern void gtk_list_store_append(GtkListStore *list_store, GtkTreeIter *iter)
void listStoreAppend(GtkListStore* list_store, GtkTreeIter *iter);

// #define listStoreAppend(l, ) gtk_list_store_append()

// 设置iter引用的行中一个或多个单元格的值。
// 变量参数列表应该包含整型列号，每个列号后面跟着要设置的值。
// 列表以-1结束。例如，要将类型G_TYPE_STRING为“Foo”的列0设置为“Foo”，
// 您可以编写gtk_list_store_set (store, iter, 0, "Foo", -1)

// void gtk_list_store_set(GtkListStore *list_store, GtkTreeIter *iter, ...)
#define listStoreSet(list_store, iter, argc...) gtk_list_store_set(list_store, iter, ##argc, -1)
typedef void(*listStoreSet)(GtkListStore *list_store, GtkTreeIter *iter, ...);
// GtkListStore* createListStore(int n_columns, ...) {
//     return gtk_list_store_new(n_columns, ...);
// }

#define listStoreClear(list_store) gtk_list_store_clear(list_store)
typedef void(*listStoreClear)(GtkListStore *list_store);

// ------------------------------------ Tree Store
// 创建可存储树
// gtk_tree_store_new(int n_columns, ...)
#define createTreeStore(n, argc...) gtk_tree_store_new(n, ##argc)
typedef void(*createTreeStore)(gint n, ...);

void treeStoreAppend(GtkTreeStore *tree_store, GtkTreeIter *iter, GtkTreeIter *parent);

#define treeStoreSet(tree_store, iter, argc...) gtk_tree_store_set(tree_store, iter, ##argc)
typedef void(*treeStoreSet)(GtkTreeStore *tree_store);

#define treeStoreClear(tree_store) gtk_tree_store_clear(tree_store);
typedef void(*treeStoreClear)(GtkTreeStore *tree_store);

// ------------------------------------ Utilities Tool

// Timer
// gboolean (*GSourceFunc)(gpointer)
#define createGSourceFunc(func) gboolean func(gpointer source)
#define createGSourceObjectFunc(func, type) gboolean func(type *source)
typedef gboolean(*createGSourceFunc);
typedef gboolean(*createGSourceObjectFunc);

#define createTimerFunc(func) createGSourceFunc(func)
#define createTimerObjectFunc(func, type) createGSourceObjectFunc(func, type)
typedef gboolean(*createTimerFunc);
typedef gboolean(*createTimerObjectFunc);

/**
 * 定时器统一管理部分，负责创建，销毁定时器
 * createTimerMilliSecond: 创建毫秒级定时器
 * createTimerSecond: 创建秒级定时器
 * timerStarted: 判断定时器是否已启动
 * stopTimer: 停止并释放定时器
 */
guint createTimerMilliSecond(guint interval, gpointer handle, gpointer data);
guint createTimerSecond(guint interval, gpointer handle, gpointer data);
gboolean timerStarted(guint *timer);
static void cleanTimer(guint *timer);
static gboolean destroyTimer(guint *timer);
gboolean stopTimer(guint *timer);

// ------------------------------------ Clipboard

// 扩展：Entry Utils
guint16 entryGetTextLength(GtkEntry *entry);
const gchar* entryGetText(GtkEntry *entry);
void entrySetText(GtkEntry *entry, const char *text);

// 获取Clipboard
#if GTK_MAJOR_VERSION == 3
typedef GtkClipboard GdkClipboard;
#endif

GdkClipboard* createClipboardWithWidget(gpointer widget);

// 设置Clipboard
void setClipboardText(GdkClipboard *clipboard, const gpointer text);

// GAsyncResult
// GAsyncReadyCallback
// void (*GAsyncReadyCallback) (GObject *source_object, GAsyncResult *res, gpointer user_data)
typedef GAsyncReadyCallback GAsyncReadyCallbackObject;
#define createGAsyncReadyCallbackFunc(func) void func(GObject *source_object, GAsyncResult *res, gpointer user_data)
#define createGAsyncReadyCallbackObjectFunc(func, type) void func(GObject *source_object, GAsyncResult *result, type *user_data)
#if GTK_MAJOR_VERSION == 3
    #define createGAsyncReadyCallbackSourceObjectFunc(func, source, type) void func(source *source_object, const gchar *text, type *user_data)
#endif
#if GTK_MAJOR_VERSION == 4
    #define createGAsyncReadyCallbackSourceObjectFunc(func, source, type) void func(source *source_object, GAsyncResult *result, type *user_data)
#endif
typedef void(*createGAsyncReadyCallbackFunc);
typedef void(*createGAsyncReadyCallbackObjectFunc);
typedef void(*createGAsyncReadyCallbackSourceObjectFunc);

// int gdk_clipboard_read_text_finish(GdkClipboard *clipboard, GAsyncResult *result, GError **error)
gchar* clipboardReadTextFinish(GdkClipboard *clipboard, GAsyncResult *result, GError **error);

// GTK 3 Clipboard Reciver [Text|Image] Callback 
// void(*GtkClipboardTextReceivedFunc)(GtkClipboard *clipboard, const gchar *text, gpointer data);
// void(*GtkClipboardImageReceivedFunc)(GtkClipboard *clipboard, GdkPixbuf *pixbuf, gpointer data);

#if GTK_MAJOR_VERSION == 3
typedef GtkClipboardTextReceivedFunc ClipboardTextReceivedCallbackObject;
#endif

typedef void(*AsyncReadyCallbackObject);
// void gdk_clipboard_read_text_async(GdkClipboard *clipboard, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
void clipboardReadTextAsync(GdkClipboard *clipboard, GCancellable *cancellable, AsyncReadyCallbackObject callback, gpointer user_data);


// PixBuf
GdkPixbuf* createPixbuferFromFile(const char *filename, GError **error);

// Image
GtkImage* createImage();
GtkImage* createImageFromFile(const char *filename);
GtkImage* createImageFromPixbuf(GdkPixbuf *pixbuf);

// #if GTK_MAJOR_VERSION == 3
#if GTK_MAJOR_VERSION == 4
// Emoji
GtkEmojiChooser* createEmojiChooser();
#endif


// Dialog
GtkDialog* createDialog();
GtkBox* dialogGetContentArea(GtkDialog *dialog);


// gtk_dialog_new_with_buttons(const char *title, GtkWindow *parent, GtkDialogFlags flags, const char *first_button_text, ..., NULL)
// const char *title, GtkWindow *parent, GtkDialogFlags flags, const char *first_button_text, ..., NULL
// GtkDialog* createDialogWithButtons(const char *title, GtkWindow *parent, GtkDialogFlags flags, const char *first_button_text, ...);
#define createDialogWithButtons(title, parent, flags, first_button_text, args...) (GtkDialog*)gtk_dialog_new_with_buttons(title, parent, flags, first_button_text, ##args, NULL);
typedef GtkDialog*(*createDialogWithButtons)(const char *title, GtkWindow *parent, GtkDialogFlags flags, const char *first_button_text, ...);

/********************************************************************************************

信号标识	触发条件
“clicked”	按下按钮时触发
“pressed”	按下按钮时触发
“released”	释放按钮时触发


鼠标事件，可以理解为操作鼠标的动作。对于窗口而言，用户操作鼠标，窗口检测到鼠标的操作( 产生一个信号 )，然后去做相应处理( 调用其规定的回调函数 )，即为鼠标事件。

窗口默认不捕获鼠标的操作，需要手动添加让其捕获：
    //添加鼠标按下事件
    //BUTTON_PRESS_MASK: 鼠标按下，触发信号"button-press-event"
    //BUTTON_RELEASE_MASK：鼠标抬起，触发"button-release-event"
    //鼠标移动都是触发"motion-notify-event"
    //BUTTON_MOTION_MASK: 鼠标移动，按下任何键移动都可以
    //BUTTON1_MOTION_MASK：鼠标移动，按住左键移动才触发
    //BUTTON2_MOTION_MASK：鼠标移动，按住中间键移动才触发
    //BUTTON3_MOTION_MASK：鼠标移动，按住右键移动才触发
    window.SetEvents(int(gdk.BUTTON_PRESS_MASK | gdk.BUTTON1_MOTION_MASK))


事件标识：
事件标识	触发条件
“button-press-event”	鼠标按下时触发
“button-release-event”	鼠标抬起时触发
“motion-notify-event”	按住鼠标移动时触发


********************************************************************************************/

#endif